package com.sanerzone.smscenter.modules.sms.web.front;
/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.sanerzone.common.support.sequence.MsgId;
import com.sanerzone.jeebase.common.config.Global;
import com.sanerzone.jeebase.common.persistence.Page;
import com.sanerzone.jeebase.common.utils.DateUtils;
import com.sanerzone.jeebase.common.utils.StringUtils;
import com.sanerzone.jeebase.common.utils.excel.ImportExcel;
import com.sanerzone.jeebase.common.web.BaseController;
import com.sanerzone.jeebase.modules.sys.utils.UserUtils;
import com.sanerzone.smscenter.biz.utils.DateHelper;
import com.sanerzone.smscenter.biz.utils.SignHelper;
import com.sanerzone.smscenter.common.message.Result;
import com.sanerzone.smscenter.common.utils.HttpRequest;
import com.sanerzone.smscenter.modules.account.entity.BaseAccount;
import com.sanerzone.smscenter.modules.account.service.BaseAccountOptionsService;
import com.sanerzone.smscenter.modules.account.service.BaseAccountService;
import com.sanerzone.smscenter.modules.sms.entity.FrontSendMessage;
import com.sanerzone.smscenter.modules.sms.entity.SmsSend;
import com.sanerzone.smscenter.modules.sms.entity.SubmitStatistics;
import com.sanerzone.smscenter.modules.sms.service.SmsReceiveService;
import com.sanerzone.smscenter.modules.sms.service.SmsSendService;
import com.sanerzone.smscenter.modules.sms.service.SmsSignService;
import com.sanerzone.smscenter.modules.sms.web.front.Entity.SendResult;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 用户发送明细Controller
 * @author zhukc
 * @version 2017-06-25
 */
@Controller
@RequestMapping(value = "/front/sendMessage")
public class FrontSendMessageController extends BaseController {

    @Autowired
    private SmsSendService smsSendService;

    @Autowired
    private SmsReceiveService smsReceiveService;

    @Autowired
    private BaseAccountService baseAccountService;

    @Autowired
    private SmsSignService smsSignService;
    @Autowired
    private BaseAccountOptionsService baseAccountOptionsService;


    //用户已发短信列表
    @RequestMapping(value = "sendList")
    public String sendList(SmsSend smsSend, HttpServletRequest request, HttpServletResponse response) {
        Result<Page<SmsSend>> result = new Result<Page<SmsSend>>();
        if (!UserUtils.getUser().isAdmin())
        {
            smsSend.setUserid(UserUtils.getUser().getId());
        }

        String tableName = "sms_send_"+DateUtils.getTableIndex(smsSend.getSendTimeQ());
        smsSend.setTableName(tableName);
        smsSend.setSendTimeZ(DateHelper.getDay(smsSend.getSendTimeQ(), 23, 59, 59));

        Page<SmsSend> page = smsSendService.findPage(new Page<SmsSend>(request, response), smsSend);
        result.setData(page);
        return renderString(response, result);
    }

    /**
     * 发送短信
     * @param msg
     * @param time
     * @param file
     * @param response
     * @return
     */
    @RequestMapping(value = "send", method= RequestMethod.POST)
    public Object send(String msg, String time, String sign, String phones, MultipartFile file, HttpServletResponse response, RedirectAttributes redirectAttributes) {

        try {
            String message = "";
            String fileName = file.getOriginalFilename();
            StringBuilder phoneBuilder = new StringBuilder();
            if (StringUtils.isNotBlank(phones)){
                if (phones.contains("\r\n")) {
                    //win
                    phones = phones.replaceAll("\r\n",",");
                } else if (phones.contains("\n")) {
                    //unix
                    phones = phones.replaceAll("\n",",");
                } else if (phones.contains("\r")) {
                    //mac
                    phones = phones.replaceAll("\r",",");
                }
                if (phones.startsWith(",")) {
                    phones = phones.substring(1);
                }
                if (phones.endsWith(",")) {
                    phones = phones.substring(0, phones.length() - 1);
                }
            }
            if (StringUtils.isNotBlank(fileName)) {
                System.out.println("文件为空");
            }
            if (StringUtils.isNotBlank(fileName)) {
                if (fileName.contains(".txt")) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        if (StringUtils.isNotBlank(line)) {
                            phoneBuilder.append(line).append(",");
                        }
                    }
                } else if (fileName.contains(".xls") || fileName.contains(".xlsx")) {
                    ImportExcel ei = new ImportExcel(file, 0, 0);
                    List<FrontSendMessage> list = ei.getDataList(FrontSendMessage.class);
                    for (FrontSendMessage frontSendMesagge : list) {
                        phoneBuilder.append(frontSendMesagge.getPhone()).append(",");
                    }
                }
                String phoneAnnex = phoneBuilder.toString();
                if (phoneBuilder.toString().startsWith(",")) {
                    phoneAnnex = phoneAnnex.substring(1,phoneBuilder.length());
                }
                if (phoneBuilder.toString().endsWith(",")) {
                    phoneAnnex = phoneAnnex.substring(0,phoneBuilder.length() - 1);
                }
                phones = phones + "," + phoneAnnex;
            }

            if (StringUtils.isBlank(phones)) {
                message = "发送手机号码为空";
                redirectAttributes.addFlashAttribute("message", message );
                return "redirect:/front/view/sendmessage";
            }
            if (StringUtils.isBlank(msg)) {
                message = "发送内容为空";
                redirectAttributes.addFlashAttribute("message", message );
                return "redirect:/front/view/sendmessage";
            }
            String signContent = SignHelper.get(msg);
            if (StringUtils.isBlank(signContent) && StringUtils.isNotBlank(sign)) {
                msg = "【"+sign+"】" + msg;
            } else  if (StringUtils.isBlank(signContent) && StringUtils.isBlank(sign)) {
                message = "短信没有签名，请在内容加签名或者使用签名";
                redirectAttributes.addFlashAttribute("message", message );
                return "redirect:/front/view/sendmessage";
            }

            String userid = UserUtils.getUser().getId();
            BaseAccount bean = new BaseAccount();
            bean.setUserid(userid);
            BaseAccount baseAccount = baseAccountService.getByUserid(bean);
            if (baseAccount == null) {
                message = "用户不存在";
                redirectAttributes.addFlashAttribute("message", message );
                return "redirect:/front/view/sendmessage";
            }
            String submitId = new MsgId(1000001).toString();
//            String result = sendedMessage(baseAccount,userid,phones,msg,time);
            SendResult sendResult=sendedMessage(baseAccount,userid,phones,msg,time,submitId);
            String result=sendResult.getResultData();
            SubmitStatistics submitStatistics=new SubmitStatistics();
            submitStatistics.setSubmitId( submitId );
            submitStatistics.setTotalCount( phones.split( "," ).length );
            submitStatistics.setSubmitTime( new Date(  ) );
            submitStatistics.setContent( msg );
            submitStatistics.setUserId( userid );
            smsSendService.insertOrder( submitStatistics );

            redirectAttributes.addFlashAttribute("message", result );
            return "redirect:/front/view/sendmessage";
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return "redirect:/front/view/sendmessage";
    }

    public SendResult sendedMessage(BaseAccount baseAccount,String userid, String phone,String msg, String time,String submitId){
        SendResult sendResult=new SendResult();
        Map<String, String> map = Maps.newHashMap();
        String ts = System.currentTimeMillis() +   "";
        String key = userid+"_"+baseAccount.getId();
        Map<String,String> options = Maps.newHashMap();
        Map<String,String> pMap = Maps.newHashMap();
        pMap.put("accId", baseAccount.getId());
        options.putAll(baseAccountOptionsService.findOptionsMap(pMap));
        String apikey =  options.get("apikey");
        if (StringUtils.isBlank(apikey)) {
            sendResult.setResultData( "apikey不存在，请联系客服" );
            return sendResult;
        }
        String apiUrl = Global.getConfig("flow.api.url");
        if (StringUtils.isBlank(apiUrl)) {
            sendResult.setResultData( "接口地址不存在，请联系客服" );
            return sendResult;
        }
        String sign = DigestUtils.md5Hex(userid + baseAccount.getId() + ts +apikey);
        Map<String, Object> patams = Maps.newHashMap();
        patams.put("userid",userid);
        patams.put("appid",baseAccount.getId());
        patams.put("ts",ts);
        patams.put("sign",sign);
        patams.put("msgcontent",msg);
        patams.put("time",time);
        patams.put( "submitId",submitId );
        boolean successFalg = false;
        String result = "";
        //提交失败手机号码
        String errorPhones = "";
        String resultData = "";
        String taskids = "";
        String failReason = "";
        int errorPhoneCount = 0;
        int successPhoneCount = 0;
        int unknownCount = 0;
        if (phone.length() > 119999) {
            successPhoneCount = -1;
            String[] mobiles = phone.split(",");
            String mobile = "";
            int count = 0;
            for (int i = 1; i < mobiles.length + 1; i++) {
                if (StringUtils.isBlank(mobiles[i-1])) {
                    continue;
                }
                count++;
                mobile += mobiles[i-1] + ",";
                if (i % 10000 == 0) {
                    patams.put("mobile",mobile.substring(0,mobile.length() -1));
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    result = HttpRequest.sendPostJson(apiUrl, JSON.toJSONString(patams), null, 3000 );
                    logger.info("客户端提交参数：[{}]，返回结果：[{}]",patams, result);
                    Map<String, Object> resultMap = resultProcess(result, count);
                    if((Boolean) resultMap.get("successFalg")) {
                        successFalg = true;
                    }
                    errorPhones += "," + resultMap.get("errorPhones");
                    taskids += "," + resultMap.get("taskid");
                    failReason += "," + resultMap.get("failReason");
                    errorPhoneCount += (Integer) resultMap.get("errorPhoneCount");
                    successPhoneCount += (Integer) resultMap.get("successPhoneCount");
                    unknownCount += (Integer) resultMap.get("unknownCount");
                    mobile = "";
                    count = 0;
                }
            }
            if (StringUtils.isNotBlank(mobile)) {
                patams.put("mobile",mobile.substring(0,mobile.length() -1));
                result = HttpRequest.sendPostJson(apiUrl, JSON.toJSONString(patams), null, 3000 );
                logger.info("客户端提交参数：[{}]，返回结果：[{}]",patams, result);
                Map<String, Object> resultMap = resultProcess(result, count);
                if((Boolean) resultMap.get("successFalg")) {
                    successFalg = true;
                }
                errorPhones += "," + resultMap.get("errorPhones");
                taskids += "," + resultMap.get("taskid");
                failReason += "," + resultMap.get("failReason");
                errorPhoneCount += (Integer) resultMap.get("errorPhoneCount");
                successPhoneCount += (Integer) resultMap.get("successPhoneCount");
                unknownCount += (Integer) resultMap.get("unknownCount");
            }
        } else {
            patams.put("mobile",phone);
            result = HttpRequest.sendPostJson(apiUrl, JSON.toJSONString(patams), null, 3000 );
            logger.info("客户端提交参数：[{}]，返回结果：[{}]",patams, result);
            int count = phone.length() - phone.replaceAll(",","").length() + 1;
            Map<String, Object> resultMap = resultProcess(result, count);
            if((Boolean) resultMap.get("successFalg")) {
                successFalg = true;
            }
            errorPhones += "," + resultMap.get("errorPhones");
            taskids += "," + resultMap.get("taskid");
            failReason += "," + resultMap.get("failReason");
            errorPhoneCount += (Integer) resultMap.get("errorPhoneCount");
            successPhoneCount += (Integer) resultMap.get("successPhoneCount");
            unknownCount += (Integer) resultMap.get("unknownCount");
        }

        logger.info("客户端发送短信userid:{}，发送状态：{}，成功个数：{}，失败个数：{}，未知个数：{}，提交单号：{}，失败号码：{}",userid, successFalg, successPhoneCount, errorPhoneCount, taskids, errorPhones);
        if (successFalg) {
            resultData = "提交成功：";
        } else {
            resultData = "提交失败：";
        }
        if (successPhoneCount > 0) {
            resultData += "成功个数："+ successPhoneCount + ",";
        }
        if (errorPhoneCount > 0) {
            resultData += "失败个数：" + errorPhoneCount + ",";
            if (failReason.length()> 0) {
                resultData += "失败原因：" + failReason + ",";
            }
            if (StringUtils.isNotBlank(errorPhones)) {
                if (errorPhones.length() < 55) {
                    resultData += "失败号码：" + errorPhones + ",";
                } else {
                    resultData += "失败号码过多请联系客服" + ",";
                }
            }
        }
        if (unknownCount > 0) {
            resultData += "未知个数：" + unknownCount + ",";
        }
        sendResult.setResultData( resultData.substring(0,resultData.length() - 1) );
        if (StringUtils.isNotBlank(taskids)) {
            sendResult.setTaskIds( taskids );
        }

        sendResult.setSubmitId( submitId );
        return sendResult;
    }

    public Map resultProcess(String result, int count){
        Map<String,Object> map = Maps.newHashMap();
        int successPhoneCount = 0;
        int errorPhoneCount = 0;
        boolean successFalg = false;
        String taskid = "";
        String errorPhones = "";
        String failReason = "";
        int unknownCount = 0;
        //result结果解析,结构{"code":"0","data":{"errorData":{"errorCode":"22","errorMsg":"部分号码提交失败,原因:号码不合法","errorPhones":["1826884021","182688746"]},"taskid":"0510121129100000142472"},"msg":"提交成功"}
        successPhoneCount = count;
        if (StringUtils.isNotBlank(result) && result.contains("code")) {
            JSONObject object = JSON.parseObject(result);
            if (StringUtils.equals(object.getString("code"),"0")) {
                successFalg = true;
                if (StringUtils.isNotBlank(object.getString("data"))) {
                    JSONObject data = JSON.parseObject(object.getString("data"));
                    if (StringUtils.isNotBlank(data.getString("taskid"))) {
                        taskid = data.getString("taskid");
                    }
                    if (StringUtils.isNotBlank(data.getString("errorData"))) {
                        JSONObject errorData = JSON.parseObject(data.getString("errorData"));
                        if (org.apache.commons.lang3.StringUtils.isNotBlank(errorData.getString("errorPhones"))) {
                            JSONArray array = JSON.parseArray(errorData.getString("errorPhones"));
                            for (int j = 0; j < array.size(); j++) {
                                if (StringUtils.isNotBlank(array.getString(j))) {
                                    errorPhones += "," + array.getString(j);
                                    errorPhoneCount++;
                                    successPhoneCount--;
                                }
                            }
                        }
                    }
                }
            } else {
                failReason = object.getString("msg") ;
                errorPhoneCount = errorPhoneCount + count;
                successPhoneCount = successPhoneCount - count;
            }
        } else {
            unknownCount = count;
            successPhoneCount = successPhoneCount - count;
        }
        if (StringUtils.isNotBlank(errorPhones)) {
            errorPhones = errorPhones.substring(1);
        }
        map.put("successFalg",successFalg);
        map.put("taskids",taskid);
        map.put("errorPhones",errorPhones);
        map.put("failReason",failReason);
        map.put("unknownCount",unknownCount);
        map.put("errorPhoneCount",errorPhoneCount);
        map.put("successPhoneCount",successPhoneCount);
        return  map;
    }
}